﻿#pragma once


#include "Containers/Vector.h"
#include "Containers/Map.h"

#include "Reflection/Reflection.h"
#include "Reflection/Type.h"
#include "Reflection/TypeID.h"
#include "Reflection/FunctionID.h"

class RObject;
class CProperty;
class CFunction;
class CClass;

class WHENGINE_API CClass:  public CType
{
public:
	CClass(CClass* InBaseClass
		,STypeID InTypeID
		,ETypeFlags InExtraFlags
		,std::function<void()> InPostConstructFunction
		)
	:CClass(InTypeID,InExtraFlags)
	{
		SetBaseType(InBaseClass);
		PostConstructFunction=InPostConstructFunction;
	}

	//this constructor is for script class only
	CClass(STypeID InTypeID,ETypeFlags InExtraFlags);


	void SetBaseType(CClass* InParentClass)
	{
		assert(!BaseType);
		BaseType=InParentClass;
		if(BaseType)
		{
			BaseType->DerivedTypes.Add(this);
		}

	}

	virtual ~CClass()
	{
		//GetAllClasses().Remove(GetName());

		RecursivelyDeleteSubClass(this);
	}


protected:

	void RecursivelyDeleteSubClass(CClass * Except)
	{
		while(SubClasses.Num())
		{
			SubClasses[0]->RecursivelyDeleteSubClass(Except);
		}

		if(BaseType)
		{
			BaseType->DerivedTypes.Remove(this);
			BaseType=nullptr;
		}

		if(this==Except)
		{
			return;
		}

		delete this;
	}

public:
	bool CanObjectConvertTo(CClass* InClass)
	{
		return this==InClass ||  IsDescendantOf(InClass);
	}

	bool IsDescendantOf(CClass* InClass)
	{
		assert(InClass);

		if (BaseType==InClass)
		{
			return true;
		}

		if(!BaseType)
		{
			return false;
		}

		return GetParentClass()->IsDescendantOf(InClass);
	}

	bool IsA(CClass * InClass)
	{
		return this==InClass || IsDescendantOf(InClass);
	}
public: 
	CClass* GetParentClass();
	TVector<CClass*> SubClasses;

	CType* SharedPtrType=nullptr;
    CType* WeakPtrType=nullptr;

	//实现的接口
	TVector<CClass*> Interfaces;

};